import serial
import time
import os
import sys
import random
import re
import subprocess
import threading



# 定义常量
DEBUG_PORT = "COM4"
AT_PORT = "COM42"
BAUDRATE = 115200
# 定义变量
at_serial = None
debug_serial = None
#记录运行次数
runTimes		= 0
#log文件
DEBUG_LOG = ""
ADB_LOG = ""
AT_LOG = ""

# 创建日志文件
def createLogFile():
    global DEBUG_LOG, ADB_LOG, AT_LOG
    timestamp = time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
    DEBUG_LOG = f"DEBUG_LOG_{timestamp}.log"
    ADB_LOG = f"ADB_LOG_{timestamp}.log"
    AT_LOG = f"AT_LOG_{timestamp}.log"
    
    with open(DEBUG_LOG, 'w', encoding='utf-8') as file:
        file.write("DEBUG 日志开始记录...\n")
    
    with open(ADB_LOG, 'w', encoding='utf-8') as file:
        file.write("ADB 日志开始记录...\n")
        
    with open(AT_LOG, 'w', encoding='utf-8') as file:
        file.write("AT 日志开始记录...\n")
        
# 写日志
def write_log(log, logFile):
    with open(logFile, 'a', encoding='utf-8') as file_object:
        file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + log + "\r\n")
        now_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        print("[" + now_time+ "]" + " " + log)

#Send at instruction
def at_write(command, timeout, at_port_opened, at_result,RDY=0,CPIN=0):
	at_command = command.encode("UTF-8")
	at_port_opened.write(at_command)
 
#读取at口返回
def at_read(serial_port, logFile=""):
 rec_str = ''
 while (True):
  time.sleep(1)
  lenth = serial_port.inWaiting()
  if lenth > 0:
   rec_str = serial_port.read(size=lenth)
   try:
    rec_str = re.sub('\\x1b.*?m', "", rec_str.decode("UTF-8"), 0, re.I)
    if logFile != "":
     with open(logFile, 'a') as file_object:
      rec_str = str(time.time()) + ":" + str(
       time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str
      file_object.write(
       str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str + "\r\n")
    return rec_str
   except:
    return ""
  else:
   break
 return rec_str

# 登录设备
def loginDevice():
 global DEBUG_LOG
 #确认登录失败的条件，或者，不可能失败
 while True:
#   print("等待登录... ... ")
  write_log("等待登录... ... ", DEBUG_LOG)
  time.sleep(3)
  at_write("\r\n",3,debug_serial,"OK")
  result = at_read(debug_serial)

  with open(DEBUG_LOG, 'a') as file_object:
   file_object.write(result)

  if "login:" in result:
   at_write("root\r\n",3,debug_serial,"OK")
#    print("账号输入成功")
   write_log("账号输入成功", DEBUG_LOG)
   time.sleep(2)
   at_write("oelinux123\r\n",3,debug_serial,"OK")
#    print("密码输入成功")
   write_log("密码输入成功", DEBUG_LOG)
  elif "~ #" in result:
#    print("登录成功")
   write_log("登录成功", DEBUG_LOG)
   break
  else:
   continue 

#检查debug口通信状态
def check_port_status():
 global debug_serial
 if debug_serial == None:
  try:
   debug_serial = serial.Serial(DEBUG_PORT,BAUDRATE)
  except:
   print("端口连接失败，请检查端口")
   sys.exit()

# 写入运行次数到日志
def writeRuntimesToLog():
 global runTimes
 with open(DEBUG_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
#  print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 with open(AT_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
#  print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 with open(ADB_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 runTimes += 1
 
#发送AT指令
def send_at_command(command):
        # 打开串口
        ser = serial.Serial(AT_PORT, BAUDRATE)
        ser.write((command + "\r\n").encode())
        ser.write(("\r\n").encode())
        time.sleep(6)
        response = ser.read_all().decode()
        ser.close()
        # write_log(f"at指令{command}执行结果:{response}",AT_LOG)
        with open(AT_LOG, 'a', encoding='utf-8') as file_object:
            file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + response + "\r\n")
        return response
        
#发送adb命令          
def send_adb_command(command):
    try:
        # 使用 subprocess 模块执行 adb shell 命令
        # 开启adb root权限
        subprocess.run(['adb', 'root'], capture_output=True, text=True)
        # 等待adb设备连接
        result = subprocess.run(['adb', 'shell', command], capture_output=True, text=True)
        with open(ADB_LOG, 'a', encoding='utf-8') as file_object:
            file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + result.stdout + "\r\n")
        # 返回命令的输出结果
        return result.stdout
    except Exception as e:
        return str(e)

# 写入运行次数到日志
def writeRuntimesToLog():
    global runTimes
    with open(DEBUG_LOG, 'a+') as file_object:
        file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20, runTimes, ">"*20))
    print("\r\n{} runtimes: {} {}\r\n".format("<"*20, runTimes, ">"*20))
    runTimes += 1
    
#设置GNSS参数
def set_gnss_parameters():
    write_log("设置GNSS参数", DEBUG_LOG)
    at_write("gnss --set fixRate 200 \r\n",3,debug_serial,"OK")
    time.sleep(2)
    at_read(debug_serial, DEBUG_LOG)
    time.sleep(2)
    

def check_gnrmc_unique_time(gnss_data_list):
    time_set = set()
    for data in gnss_data_list:
        match = re.match(r'\$GNRMC,([^,]*),', data)
        if match:
            utc_time = match.group(1)
            if utc_time in time_set:
                return False  # 存在重复的时间
            time_set.add(utc_time)

    return True  # 所有时间均唯一

def start_gnss():
    write_log("启动GNSS", DEBUG_LOG)
    at_write("gnss --start\r\n", 3, debug_serial, "OK")
    time.sleep(5)
    gnss_results = []
    for i in range(20):
        gnss_result = at_read(debug_serial, DEBUG_LOG)
        # 将每次的gnss_res结果追加到列表中
        gnss_results.append(gnss_result)
        # 匹配 GNRMC 语句，检查是否包含 'A'
        if re.search(r'\$GNRMC,[^,]*,A,', gnss_result):
            write_log("GNSS 定位成功", DEBUG_LOG)
    
    # print(gnss_results)
    if check_gnrmc_unique_time(gnss_results):
        write_log("GNRMC 时间无重复", DEBUG_LOG)
    else:
        write_log("GNRMC 时间有重复", DEBUG_LOG)
    
    # 返回gnss_res列表或将其用于进一步处理
    return gnss_results
   
#模块重启
def restart_module():
    at_write(chr(3), 3, debug_serial, "OK")
    write_log("重启模块", DEBUG_LOG)
    at_write("\r\nreboot\r\n", 3, debug_serial, "OK")
    time.sleep(60)
    at_read(debug_serial, DEBUG_LOG)
    

check_port_status()
createLogFile()
print(f"DEBUG_LOG: {DEBUG_LOG}, ADB_LOG: {ADB_LOG}, AT_LOG: {AT_LOG}")
while True:
    loginDevice()
    set_gnss_parameters()
    start_gnss()
    restart_module()